package com.xja.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.xja.exception.CustomException;
import com.xja.mapper.ArticleMapper;
import com.xja.model.dto.ArticlePublishDTO;
import com.xja.model.entity.Article;
import com.xja.model.entity.ArticleLike;
import com.xja.model.entity.Comment;
import com.xja.model.entity.CommentLike;
import com.xja.model.vo.resp.ArticleDetailVO;
import com.xja.model.vo.resp.ArticleItemVO;
import com.xja.service.IArticleLikeService;
import com.xja.service.IArticleService;
import com.xja.service.IUserService;
import com.xja.utils.UserContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * 文章表 服务实现类
 * </p>
 *
 * @author caijg
 
 */
@Service
@Slf4j
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements IArticleService {

    @Autowired
    private IUserService userService;
    @Autowired
    private IArticleLikeService articleLikeService;

    @Override
    public void publish(ArticlePublishDTO articlePublishDTO) {
        // 1.获取当前用户
        Long uid = UserContext.getUid();

        // 2.填充一些字段
        Article article = BeanUtil.toBean(articlePublishDTO, Article.class);
        // 2.1设置作者id
        article.setAuthorId(uid);
        // 2.2设置状态为审核中
        article.setStatus(0);
        // 2.3设置创建时间
        article.setCreateTime(LocalDateTime.now());
        article.setUpdateTime(LocalDateTime.now());
        // 2.4初始化一些字段
        article.setCommentCount(0L);
        article.setLikeCount(0L);
        article.setViewCount(0L);

        // 3.保存到数据库
        this.save(article);
    }

    @Override
    public List<ArticleItemVO> getList(String searchText) {
        // 1.获取文章列表
        List<Article> list = this.query()
                .eq("status", 1) // 状态为已发布的
                .like(StrUtil.isNotBlank(searchText), "title", searchText) // 模糊查询
                .orderByDesc("like_count") // 按照点赞数降序
                .orderByDesc("view_count") // 按照浏览数降序
                .list();
        // 2.封装VO
        List<ArticleItemVO> articleItemVOList = list.stream().map(article -> ArticleItemVO.builder()
               .id(article.getId())
               .title(article.getTitle())
               .description(article.getDescription())
               .coverImage(article.getCoverImage())
               .author(userService.query()
                       .eq("id", article.getAuthorId())
                       .one()
                       .getNickname())
               .likes(article.getLikeCount())
                .isLiked(articleLikeService.query()
                        .eq("article_id", article.getId())
                        .eq("user_id", UserContext.getUid())
                        .exists())
               .views(article.getViewCount())
               .createTime(article.getCreateTime())
               .build()).toList();

        return articleItemVOList;
    }

    @Override
    public ArticleDetailVO getDetail(Long id) {
        // 1.获取文章详情
        Article article = this.query()
                .eq("id", id)
                .one();

        // 2.封装VO
        ArticleDetailVO articleDetailVO = BeanUtil.toBean(article, ArticleDetailVO.class);
        articleDetailVO.setAuthor(userService.query()
                .eq("id", article.getAuthorId())
                .one()
                .getNickname());

        // 3.返回
        return articleDetailVO;
    }

    @Override
    public Boolean checkLikeStatus(Long articlId) {
        // 1.获取当前用户id
        Long uid = UserContext.getUid();
        // 2.查询点赞记录

        return articleLikeService.query()
                .eq("user_id", uid)
                .eq("article_id", articlId)
                .exists();
    }

    @Override
    public Boolean like(Long articlId) {
        // 1.获取当前用户id
        Long uid = UserContext.getUid();

        // 2.查询点赞记录
        ArticleLike one = articleLikeService.query()
                .eq("user_id", uid)
                .eq("article_id", articlId)
                .one();

        // 3.判断点赞记录是否存在
        if (one != null) { // 点赞记录存在，取消点赞
            articleLikeService.removeById(one.getId());
            // 更新文章点赞数-1
            Article article = this.query().eq("id", articlId).one();
            this.updateById(article.setLikeCount(article.getLikeCount() - 1));
            return false;
        } else {
            // 4.点赞记录不存在，新增点赞记录
            ArticleLike articleLike = new ArticleLike();
            articleLike.setUserId(uid);
            articleLike.setArticleId(articlId);
            articleLikeService.save(articleLike);
            // 更新文章点赞数
            Article article = this.query().eq("id", articlId).one();
            this.updateById(article.setLikeCount(article.getLikeCount() + 1));
            return true;
        }
    }

    @Override
    public void views(Long articleId) {
        // 1.更新浏览量
        this.update()
                .eq("id", articleId)
                .setSql("view_count = view_count + 1")
                .update();
    }

    @Override
    public List<Article> getMyLoveArticle() {
        // 1.获取当前用户id
        Long uid = UserContext.getUid();
        // 2.查询点赞记录
        List<ArticleLike> articleLikeList = articleLikeService.query()
                .eq("user_id", uid)
                .list();

        if (CollUtil.isEmpty(articleLikeList)) {
            return Collections.emptyList();
        }
        // 3.根据点赞记录查询文章
        List<Article> articleList = this.query()
                .in("id",
                        articleLikeList.stream()
                        .map(ArticleLike::getArticleId)
                        .toList())
                .list();

        return articleList;
    }

    @Override
    public List<Article> getMyArticle() {
        // 1.获取当前用户id
        Long uid = UserContext.getUid();
        // 2.查询文章
        List<Article> articleList = this.query()
                .eq("author_id", uid)
                .list();
        return articleList;
    }

    @Override
    public Boolean delete(ArrayList<String> ids) {
        if (CollUtil.isEmpty(ids)) {
            throw new CustomException("文章不存在", 500);
        }
        // 1. 删除文章
        this.removeByIds(ids);
        // 2. 删除文章点赞记录
        if (CollUtil.isNotEmpty(ids)) {
            articleLikeService.update()
                    .in("article_id", ids)
                    .remove();
        }
        // 3. 删除文章评论记录
        List<Long> commentIds = Db.query(Comment.class)
                .in("article_id", ids)
                .list()
                .stream()
                .map(Comment::getId)
                .toList();
        if (CollUtil.isNotEmpty(commentIds)) {
            Db.update(Comment.class)
                    .in("id", commentIds)
                    .remove();
            // 4. 删除评论-点赞记录
            Db.update(CommentLike.class)
                    .in("comment_id", commentIds)
                    .remove();
        }
        return true;
    }
}